/* Copyright (C) 2005 - 2007 the patternCoder team, http://www.patterncoder.org

 This file is part of the patternCoder application

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.patterncoder.utils;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import org.patterncoder.PatternCoder;
import org.patterncoder.dataModel.Pattern;
import org.patterncoder.dataModel.PatternComponent;
import org.patterncoder.system.AbstractSystem;
import static org.patterncoder.system.AbstractSystem.SEPARATOR;

/**
 * Encapsulates utils methods
 *
 * @author Florian Siebler
 */
public class Utils
{
    private Utils()
    {
    }

    /**
     * Checks a source name against a list of invalid characters. Returns a
     * boolean value indicating whether the name is valid or not.
     *
     * @param name The name that requires a check for invalid characters
     * @return Returns true if the name is well formated and valid. Return false
     * if the name is invalid.
     */
    public static boolean verifyName(String name)
    {
        char[] INVALID_CHARS =
        {
            '!', '"', '%', '`', ' ', '~', '#', '^', '&', '*', '(', ')', '+', '=',
            '{', '}', '[', ']', '@', ':', ';', '?', '>', '<', '|'
        };
        boolean wellFormed = true;

        if (name == null || name.isEmpty())
        {
            wellFormed = false;
        }
        else
        {
            for (int i = 0; i < INVALID_CHARS.length; i++)
            {
                Character check = INVALID_CHARS[i];
                if (name.contains(check.toString()))
                {
                    wellFormed = false;
                    break;
                }
            }
        }
        return wellFormed;
    }

    /**
     * PatternImplementer generates all sources needed for a particular pattern,
     * and is used to add them to the BlueJ project. <p> Generates first of all
     * the java source file for each of the components and copies them to the
     * correct project directory. <p> The classes are then added to the project,
     * and the package reloaded in order to display all associations between
     * classes.
     *
     * @author Michael Nairn
     * @throws IOException
     */
    public static void createFiles(Pattern currentPattern) throws IOException
    {
        final String CLASS_NAME = "\\$CLASSNAME";
        final String PACKAGE_LINE = "\\$PKGLINE";
        final String DEPENDANT_CLASS = "\\$DEPENDANT";
        final String AUTHOR = "(your name)";
        final String USER_NAME = System.getProperty("user.name");
        final PatternComponent[] ALL_COMPONENTS = currentPattern.getAllComponents();
        final AbstractSystem SYSTEM = PatternCoder.getSystem();
        String packageName = SYSTEM.getPackageName();

        String packageLine = "";
        if (packageName != null && !packageName.isEmpty())
        {
            packageLine = "package " + packageName + ";";
        }

        String projectDir = SYSTEM.getProjectDir() + SEPARATOR;

        for (PatternComponent tempCompo : ALL_COMPONENTS)
        {
            String tempClassName = tempCompo.getClassName();
            String filename = projectDir
                    + tempClassName + ".java";

            String template = tempCompo.getTemplate();
            template = template.replaceAll(CLASS_NAME, tempClassName);
            template = template.replaceAll(PACKAGE_LINE, packageLine);
            template = template.replaceAll(AUTHOR, USER_NAME);

            String[] deps = tempCompo.getAllDependencies();
            for (String dep : deps)
            {
                String expression = DEPENDANT_CLASS + dep;
                int componentID = Integer.parseInt(dep) - 1;
                String classNameOfDep = currentPattern.getComponent(componentID).getClassName();
                template = template.replaceAll(expression, classNameOfDep);
            }
            template = template.concat("\n\n/*\n"
                    + " * Source file generated by patternCoder for BlueJ Version "
                    + PatternCoder.VERSION + ".\n"
                    + " * For more info, please visit"
                    + PatternCoder.EXT_URL + "\n " + "*/");
            writeUTF8(filename, template);
        }
        SYSTEM.reload();
    }

    /**
     * Writes a text file in UTF8
     *
     * @param textFileName Name of target file
     * @param content // * Content of file
     * @throws IOException
     */
    private static void writeUTF8(String textFileName, String content)
            throws IOException
    {
        FileOutputStream fos = new FileOutputStream(textFileName);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter wr = new BufferedWriter(osw);
        wr.write(content);
        wr.close();
        osw.close();
        fos.close();
    }
}
